package com.view;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.FrameLayout;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.util.LogUtil;
import com.util.R;
import com.util.ScreenUtil;

/**
 * Created by Administrator on 2016/7/1.
 */
public class DropDownAndPullUpLayout extends FrameLayout {
    private Context context;
    //FootView
    private RelativeLayout footView;
    private ImageView footViewLeftImg;
    private TextView footViewText;
    //HeadView
    private RelativeLayout headView;
    private ImageView headViewLeftImg;
    private TextView headViewText;
    private float damping = 0.6f; //阻尼系数
    private float downYonInterceptTouchEvent; //按下的Y坐标
    float dyOnTouchEvent; //两次滑动的差值
    private ObjectAnimator releaseObjectAnimator; //松开手后的动画
    private RotateAnimation rotateAnimation; //旋转动画
    private float moveYOnTouchEvent; //滑动过程中的Y坐标
    private boolean isRefreshOrLoading = false; //是否正在刷新或加载
    private boolean isContentRefreshOrLoad = false; //是否满足刷新或加载条件
    private RefreshListener refreshListener;
    private LoadMoreListener loadMoreListener;
    private boolean isFirstAddView = true; //首次添加View
    private int type=Type.DROP_AND_PULL; //类型(只能上拉，只能下拉，同时能上下拉)
    private String status=""; //状态(下拉或上拉)
    //支持三种滑动的View
    private ListView listView;
    private GridView gridView;
    private RecyclerView recyclerView;
    private int addWhichView = -1; //判断传入的是哪种类型的View
    //从布局中传入的参数
    private float headFootViewHeightScale = 0.085f;
    private float headFootViewHeight = ScreenUtil.getScreenHeight() * headFootViewHeightScale;
    private int behindBackGround = Color.DKGRAY;
    private int headFootViewTextColor = Color.WHITE;
    private int dropDownImg = R.mipmap.arrow_down;
    private int pullUpImg = R.mipmap.arrow_up;
    private int loadingImg = R.mipmap.refreshing;

    public DropDownAndPullUpLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        initAttrs(attrs);
        initRefreshLodeMoreLayout();
    }

    private void initAttrs(AttributeSet attrs) {
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DropDownAndPullUpLayout);
        int n = a.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = a.getIndex(i);
            switch (attr) {
                case R.styleable.DropDownAndPullUpLayout_behindBackGround:
                    behindBackGround = a.getColor(attr, Color.DKGRAY);
                    break;
                case R.styleable.DropDownAndPullUpLayout_headFootViewHeightScale:
                    headFootViewHeightScale = a.getFloat(attr, 0.085f);
                    headFootViewHeight = ScreenUtil.getScreenHeight() * headFootViewHeightScale;
                    break;
                case R.styleable.DropDownAndPullUpLayout_damping:
                    damping = a.getFloat(attr, 0.6f);
                    break;
                case R.styleable.DropDownAndPullUpLayout_headFootViewTextColor:
                    headFootViewTextColor = a.getColor(attr, Color.WHITE);
                    break;
                case R.styleable.DropDownAndPullUpLayout_dropDownImg:
                    dropDownImg = a.getResourceId(attr, R.mipmap.arrow_down);
                    break;
                case R.styleable.DropDownAndPullUpLayout_pullUpImg:
                    pullUpImg = a.getResourceId(attr, R.mipmap.arrow_up);
                    break;
                case R.styleable.DropDownAndPullUpLayout_loadingImg:
                    loadingImg = a.getResourceId(attr, R.mipmap.refreshing);
                    break;
                case R.styleable.DropDownAndPullUpLayout_type:
                    type = a.getInteger(attr, 2);
                    break;
            }
        }
        a.recycle();
    }

    private void initRefreshLodeMoreLayout() {
        initHeadView();
        initFootView();
        ViewTreeObserver observer = getViewTreeObserver();
        observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { //检测ViewGroup是否完成初始化工作
            @Override
            public void onGlobalLayout() {
                getViewTreeObserver().removeGlobalOnLayoutListener(this);
                if (isFirstAddView) {
                    setBackgroundColor(behindBackGround);
                    if (getChildCount() != 1) {
                        throw new IllegalArgumentException("只能传入一个ListView或GridView或RecyclerView");
                    }
                    View child = getChildAt(0);
                    if (!(child instanceof ListView || child instanceof GridView || child instanceof RecyclerView)) {
                        throw new IllegalArgumentException("只能传入一个ListView或GridView或RecyclerView");
                    }
                    if (child instanceof ListView) {
                        listView = (ListView) getChildAt(0);
                        addWhichView = 0;
                    } else if (child instanceof GridView) {
                        gridView = (GridView) getChildAt(0);
                        addWhichView = 1;
                    } else if (child instanceof RecyclerView) {
                        recyclerView = (RecyclerView) getChildAt(0);
                        addWhichView = 2;
                    }
                    removeAllViews(); //先移除布局中的View

                    FrameLayout.LayoutParams headViewLayoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) headFootViewHeight);
                    headViewLayoutParams.gravity = Gravity.TOP;
                    addView(headView, headViewLayoutParams);

                    FrameLayout.LayoutParams footViewLayoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) headFootViewHeight);
                    footViewLayoutParams.gravity = Gravity.BOTTOM;
                    addView(footView, footViewLayoutParams);
                    FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
                    switch (addWhichView) {
                        case 0:
                            addView(listView, params);
                            break;
                        case 1:
                            addView(gridView, params);
                            break;
                        case 2:
                            addView(recyclerView, params);
                            break;
                    }
                    isFirstAddView = false;
                }
            }
        });
    }

    //初始化HeadView
    private void initHeadView() {
        headView = new RelativeLayout(context);
        headViewText = new TextView(context);
        headViewText.setTextSize(headFootViewHeight * 0.15f);
        headViewText.setText("下拉刷新");
        headViewText.setTextColor(headFootViewTextColor);
        RelativeLayout.LayoutParams textParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        textParams.addRule(RelativeLayout.CENTER_IN_PARENT);
        headView.addView(headViewText, textParams);
        headViewLeftImg = new ImageView(context);
        headViewLeftImg.setImageResource(R.mipmap.arrow_down);
        RelativeLayout.LayoutParams imgParams = new RelativeLayout.LayoutParams((int) (headFootViewHeight * 0.35f), (int) (headFootViewHeight * 0.35f));
        imgParams.addRule(RelativeLayout.CENTER_VERTICAL);
        imgParams.leftMargin = (int) (headFootViewHeight * 0.8f);
        headView.addView(headViewLeftImg, imgParams);
    }

    //初始化footView
    private void initFootView() {
        footView = new RelativeLayout(context);
        footViewText = new TextView(context);
        footViewText.setTextSize(headFootViewHeight * 0.15f);
        footViewText.setText("上拉加载更多");
        footViewText.setTextColor(headFootViewTextColor);
        RelativeLayout.LayoutParams textParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        textParams.addRule(RelativeLayout.CENTER_IN_PARENT);
        footView.addView(footViewText, textParams);
        footViewLeftImg = new ImageView(context);
        footViewLeftImg.setImageResource(R.mipmap.arrow_up);
        RelativeLayout.LayoutParams imgParams = new RelativeLayout.LayoutParams((int) (headFootViewHeight * 0.35f), (int) (headFootViewHeight * 0.35f));
        imgParams.addRule(RelativeLayout.CENTER_VERTICAL);
        imgParams.leftMargin = (int) (headFootViewHeight * 0.8f);
        footView.addView(footViewLeftImg, imgParams);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (isRefreshOrLoading) {
            return true;
        }
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
//                LogUtil.i("test", "ACTION_DOWN");
                downYonInterceptTouchEvent = ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                float moveY = ev.getY() - downYonInterceptTouchEvent;

                if (moveY > 0 && !canScrollDown()) {
                    if (type == Type.DROP_DOWN || type == Type.DROP_AND_PULL) {
                        status = "DropDown";
                        LogUtil.i("test", "status:" + status);
                    }
                    return true;
                } else if (moveY < 0 && !canScrollUp()) {
                    if (type == Type.PULL_UP || type == Type.DROP_AND_PULL) {
                        status = "PullUp";
                        LogUtil.i("test", "status:" + status);
                    }
                    return true;
                }
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (isRefreshOrLoading) {
            return super.onTouchEvent(event);
        }
        switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:
                moveYOnTouchEvent = event.getY();
                dyOnTouchEvent = moveYOnTouchEvent - downYonInterceptTouchEvent;
//                LogUtil.i("test", "dy:" + dyOnTouchEvent);
//                LogUtil.i("test", "headFootViewHeight:" + headFootViewHeight);
                if (dyOnTouchEvent < 0 && status.equals("PullUp") && !isHaveNoData()) {
                    if (Math.abs(dyOnTouchEvent) > headFootViewHeight * 2.5) {
                        footViewLeftImg.setImageResource(dropDownImg);
                        footViewText.setText("释放立即加载");
                    } else {
                        footViewLeftImg.setImageResource(pullUpImg);
                        footViewText.setText("上拉加载更多");
                    }
                } else if (dyOnTouchEvent > 0 && status.equals("DropDown")) {
                    if (Math.abs(dyOnTouchEvent) > headFootViewHeight * 2.5) {
                        headViewLeftImg.setImageResource(pullUpImg);
                        headViewText.setText("释放立即刷新");
                    } else {
                        headViewLeftImg.setImageResource(dropDownImg);
                        headViewText.setText("下拉刷新");
                    }
                }

                if(status.equals("PullUp")){
                    if(dyOnTouchEvent>=0){
                        setViewTranslationY(0);
                        return true;
                    }
                    setViewTranslationY(dyOnTouchEvent - dyOnTouchEvent * damping);
                }else if(status.equals("DropDown")){
                    if(dyOnTouchEvent<=0){
                        setViewTranslationY(0);
                        return true;
                    }
                    setViewTranslationY(dyOnTouchEvent - dyOnTouchEvent * damping);
                }
                return true;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                if (releaseObjectAnimator == null) {
                    releaseObjectAnimator = new ObjectAnimator();
                    switch (addWhichView) {
                        case 0:
                            releaseObjectAnimator.setTarget(listView);
                            break;
                        case 1:
                            releaseObjectAnimator.setTarget(gridView);
                            break;
                        case 2:
                            releaseObjectAnimator.setTarget(recyclerView);
                            break;
                    }
                    releaseObjectAnimator.setPropertyName("translationY");
                    releaseObjectAnimator.setDuration(300);
                    releaseObjectAnimator.addListener(new Animator.AnimatorListener() {
                        @Override
                        public void onAnimationStart(Animator animation) {
                        }

                        @Override
                        public void onAnimationEnd(Animator animation) {
                            if (isContentRefreshOrLoad) {
                                if (rotateAnimation == null) {
                                    rotateAnimation = new RotateAnimation(0, 48000, // 0~360度
                                            Animation.RELATIVE_TO_SELF, 0.5f, //
                                            // 相对于原点的x坐标,0.5表示以父容器宽度的一半为距离得到圆心的x坐标
                                            Animation.RELATIVE_TO_SELF, 0.5f); //
                                    rotateAnimation.setAnimationListener(new Animation.AnimationListener() {
                                        @Override
                                        public void onAnimationStart(Animation animation) {

                                        }

                                        @Override
                                        public void onAnimationEnd(Animation animation) {
                                            restore();
                                        }

                                        @Override
                                        public void onAnimationRepeat(Animation animation) {

                                        }
                                    });
                                    // 相对于原点的y坐标,0.5表示以父容器高度的一半为距离得到圆心的y坐标
                                    rotateAnimation.setInterpolator(new LinearInterpolator());
                                    rotateAnimation.setDuration(60000);

                                }
                                if (status.equals("PullUp")) {
                                    footViewLeftImg.setImageResource(loadingImg);
                                    footViewLeftImg.startAnimation(rotateAnimation);
                                    footViewText.setText("正在加载...");
                                    if (loadMoreListener != null) {
                                        loadMoreListener.onLoadMore();
                                    }

                                } else if (status.equals("DropDown")) {
                                    headViewLeftImg.setImageResource(loadingImg);
                                    headViewLeftImg.startAnimation(rotateAnimation);
                                    headViewText.setText("正在刷新...");
                                    if (refreshListener != null) {
                                        refreshListener.onRefreshing();
                                    }
                                }
                                return;
                            }
                            restore();
                        }

                        @Override
                        public void onAnimationCancel(Animator animation) {

                        }

                        @Override
                        public void onAnimationRepeat(Animator animation) {

                        }
                    });
                }
                isRefreshOrLoading = true;
                float scrollDistance=0;
                switch (addWhichView){
                    case 0:
                        scrollDistance = listView.getTranslationY();
                        break;
                    case 1:
                        scrollDistance = gridView.getTranslationY();
                        break;
                    case 2:
                        scrollDistance = recyclerView.getTranslationY();
                        break;
                }
//LogUtil.i("test","dy:"+dyOnTouchEvent);
//LogUtil.i("test","scrollDistance:"+scrollDistance);
//LogUtil.i("test","headFootViewHeight:"+headFootViewHeight * 2.5);
                if (Math.abs(dyOnTouchEvent) > headFootViewHeight * 2.5&&Math.abs(scrollDistance)>0) { //满足上拉刷新条件
                    if (status.equals("PullUp")) {
                        isContentRefreshOrLoad = true;
                        setViewObjectAnimatorFloatValue(-(int) (headFootViewHeight));
                        releaseObjectAnimator.start();
                    } else if (status.equals("DropDown")) {
                        isContentRefreshOrLoad = true;
                        setViewObjectAnimatorFloatValue((int) (headFootViewHeight));
                        releaseObjectAnimator.start();
                    } else {
                        restore();
                    }
                } else {
                    if (status.equals("PullUp")||status.equals("DropDown")) {
                        setViewObjectAnimatorFloatValue(0);
                        releaseObjectAnimator.start();
                    } else {
                        restore();
                    }
                }
                return true;
            default:
                return super.onTouchEvent(event);
        }
    }

    //恢复状态
    private void restore() {
        isRefreshOrLoading = false;
        status = "";
    }

    //设置用户手指拖动的值
    private void setViewTranslationY(float dy) {
        switch (addWhichView) {
            case 0:
                listView.setTranslationY(dy);
                break;
            case 1:
                gridView.setTranslationY(dy);
                break;
            case 2:
                recyclerView.setTranslationY(dy);
                break;
        }
    }

    //设置动画在Y方向上移动的值
    private void setViewObjectAnimatorFloatValue(int i) {
        switch (addWhichView) {
            case 0:
                releaseObjectAnimator.setFloatValues(listView.getTranslationY(), i);
                break;
            case 1:
                releaseObjectAnimator.setFloatValues(gridView.getTranslationY(), i);
                break;
            case 2:
                releaseObjectAnimator.setFloatValues(recyclerView.getTranslationY(), i);
                break;
        }
    }

    //是否可以上拉
    private boolean canScrollUp() {
        switch (addWhichView) {
            case 0:
                return ViewCompat.canScrollVertically(listView, 0);
            case 1:
                return ViewCompat.canScrollVertically(gridView, 0);
            case 2:
                return ViewCompat.canScrollVertically(recyclerView, 0);
        }
        return false;
    }

    //是否可以下拉
    private boolean canScrollDown() {
        switch (addWhichView) {
            case 0:
                return ViewCompat.canScrollVertically(listView, -1);
            case 1:
                return ViewCompat.canScrollVertically(gridView, -1);
            case 2:
                return ViewCompat.canScrollVertically(recyclerView, -1);
        }
        return false;
    }

    public void setRefreshListener(RefreshListener listener) {
        if (!(type == 0 || type == 2)) {
            throw new RuntimeException("请确定当前为下拉或上下拉模式");
        }
        this.refreshListener = listener;
    }

    public void setLoadMoreListener(LoadMoreListener loadMoreListener) {
        if (!(type == 1 || type == 2)) {
            throw new RuntimeException("请确定当前为上拉或上下拉模式");
        }
        this.loadMoreListener = loadMoreListener;
    }

    //加载更多完成
    public void onLoadMoreCompleted() {
        footViewLeftImg.clearAnimation();
        isContentRefreshOrLoad = false;
        setViewObjectAnimatorFloatValue(0);
        releaseObjectAnimator.start();
    }

    //下拉刷新完成
    public void onRefreshCompleted() {
        headViewLeftImg.clearAnimation();
        isContentRefreshOrLoad = false;
        setViewObjectAnimatorFloatValue(0);
        releaseObjectAnimator.start();
    }

    //是否存在数据
    private boolean isHaveNoData() {
        switch (addWhichView) {
            case 0:
                return listView.getAdapter().getCount() == 0;
            case 1:
                return gridView.getAdapter().getCount() == 0;
            case 2:
                return recyclerView.getAdapter().getItemCount() == 0;
        }
        return false;
    }

    public interface RefreshListener {
        void onRefreshing();
    }

    public interface LoadMoreListener {
        void onLoadMore();
    }

    //类型(下拉，上拉，上下拉)
    public class Type {
        public final static int DROP_DOWN = 0;
        public final static int PULL_UP = 1;
        public final static int DROP_AND_PULL = 2;
    }
}


